package beans;

import java.util.Date;

import java.util.TimeZone;

import oracle.adf.view.rich.event.CalendarActivityEvent;

import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import javax.servlet.http.HttpSession;

import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCIteratorBinding;
import oracle.adf.view.rich.component.rich.RichPopup;
import oracle.adf.view.rich.datatransfer.DataFlavor;
import oracle.adf.view.rich.datatransfer.Transferable;
import oracle.adf.view.rich.dnd.CalendarDropSite;
import oracle.adf.view.rich.dnd.DnDAction;
import oracle.adf.view.rich.event.CalendarActivityEvent;
import oracle.adf.view.rich.event.CalendarEvent;
import oracle.adf.view.rich.event.DropEvent;
import oracle.adf.view.rich.event.PopupFetchEvent;

import oracle.adf.view.rich.model.CalendarActivity;

import oracle.adf.view.rich.model.CalendarModel;

import oracle.binding.AttributeBinding;
import oracle.binding.BindingContainer;
import oracle.binding.ControlBinding;
import oracle.binding.OperationBinding;

import oracle.jbo.Key;
import oracle.jbo.Row;

import oracle.jbo.RowSetIterator;

import org.apache.myfaces.trinidad.model.RowKeySet;
import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;

public class CalendarBusiness {
    private RichPopup updatePopup;
    private RichPopup createPopup;
    private CalendarModel calendarModel;
    private TimeZone timeZone = TimeZone.getDefault();

    public CalendarBusiness() {

    }


    public BindingContainer getBindings() {
        return BindingContext.getCurrent().getCurrentBindingsEntry();
    }

    public void hidePopup(RichPopup popup) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExtendedRenderKitService service = Service.getRenderKitService(facesContext, ExtendedRenderKitService.class);
        service.addScript(facesContext,
                          "AdfPage.PAGE.findComponent('" + popup.getClientId(facesContext) + "').hide();");
    }

    public void onDelete(ActionEvent actionEvent) {
        BindingContainer bindings = getBindings();
        OperationBinding operationBinding = bindings.getOperationBinding("Delete");
        operationBinding.execute();
        if (operationBinding.getErrors().isEmpty()) {
            operationBinding = bindings.getOperationBinding("Commit");
            operationBinding.execute();
        }
    }

    public void onSave(ActionEvent actionEvent) {
        BindingContainer bindings = getBindings();
        OperationBinding operationBinding = bindings.getOperationBinding("Commit");
        operationBinding.execute();
        if (operationBinding.getErrors().isEmpty()) {
            if (actionEvent.getComponent().getId().equals("cb3")) {
                hidePopup(getUpdatePopup());
            } else {
                hidePopup(getCreatePopup());
            }

        }
    }

    public void onUndo(ActionEvent actionEvent) {
        DCBindingContainer dcbindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
        DCIteratorBinding iterator = dcbindings.findIteratorBinding("CalendarView1Iterator");
        Row currentRow = iterator.getCurrentRow();

        if (currentRow != null) {
            currentRow.refresh(Row.REFRESH_UNDO_CHANGES);
        }
    }

    public void onCancel(ActionEvent actionEvent) {
        DCBindingContainer dcbindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
        DCIteratorBinding iterator = dcbindings.findIteratorBinding("CalendarView1Iterator");
        Row currentRow = iterator.getCurrentRow();

        if (actionEvent.getComponent().getId().equals("cb6")) {
            if (currentRow != null) {
                currentRow.refresh(Row.REFRESH_UNDO_CHANGES);
            }
            hidePopup(getUpdatePopup());
        }

        else {
            BindingContainer bindings = getBindings();
            OperationBinding operationBinding = bindings.getOperationBinding("Delete");
            operationBinding.execute();

            hidePopup(getCreatePopup());
        }
    }

    //when the create popup is launched a CreateInsert operation is executed upon the CalendarViewIterator to host the new activity that is to be created

    public void onPopupFetch(PopupFetchEvent popupFetchEvent) {
        BindingContainer bindings = getBindings();
        OperationBinding operationBinding = bindings.getOperationBinding("CreateInsert");
        operationBinding.execute();
    }

    public void setUpdatePopup(RichPopup updatePopup) {
        this.updatePopup = updatePopup;
    }

    public RichPopup getUpdatePopup() {
        return updatePopup;
    }

    public void setCreatePopup(RichPopup createPopup) {
        this.createPopup = createPopup;
    }

    public RichPopup getCreatePopup() {
        return createPopup;
    }
    //method used in order to syncronize the CalendarViewIterator with the af:calendar component
    //when an activity event occurs the CalendarViewIterator current row is updated to match the selected activity in the UI

    public void activityListener(CalendarActivityEvent calendarActivityEvent) {
        CalendarActivity activity = calendarActivityEvent.getCalendarActivity();

        if (activity != null) {
            DCBindingContainer dcbindings = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
            DCIteratorBinding iterator = dcbindings.findIteratorBinding("CalendarView1Iterator");
            Key key = new Key(new Object[] { activity.getId() });
            RowSetIterator rsi = iterator.getRowSetIterator();
            Row row = rsi.findByKey(key, 1)[0];
            rsi.setCurrentRow(row);
        }
    }


    //////////////////////////////////////////////


    public DnDAction handleDrop(DropEvent dropEvent) {
        return _handleDrop(dropEvent, false);
    }

    public DnDAction handleDropWithPopup(DropEvent dropEvent) {
        return _handleDrop(dropEvent, true);
    }

    public DnDAction _handleDrop(DropEvent dropEvent, boolean showPopup) {
        Transferable transferable = dropEvent.getTransferable();
        CalendarDropSite dropSite = (CalendarDropSite)dropEvent.getDropSite();
        Date dropSiteDate = dropSite.getDate();
        CalendarActivity.TimeType timeType = dropSite.getTimeType();

        CalendarActivity activity =
            (CalendarActivity)transferable.getData(DataFlavor.getDataFlavor(CalendarActivity.class));

        // If we have a calendar activitity that we are moving within the same view
        if (activity != null) {
            //  _handleCalendarActivityDrop(dropEvent, dropSiteDate, activity, showPopup);
            return dropEvent.getProposedAction();
        }

        // See if we have a drag and drop of a row to create a new activity.
        DataFlavor<RowKeySet> rowKeySetFlavor = DataFlavor.getDataFlavor(RowKeySet.class, "DnDAcivityModel");
        RowKeySet rowKeySet = transferable.getData(rowKeySetFlavor);
        if (rowKeySet != null) {
            // _handleRowKeyDrop(dropEvent, transferable, dropSiteDate, timeType, rowKeySet, showPopup);
            return dropEvent.getProposedAction();
        }

        return DnDAction.NONE;
    }

    public void setTimeZone(TimeZone timeZone) {
        this.timeZone = timeZone;
    }

    public TimeZone getTimeZone() {
        return timeZone;
    }

}
